package priv.blackbibo.application.service;

import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Environment;
import android.os.IBinder;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.Nullable;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import priv.blackbibo.application.R;

/**
 * Created by black on 2019-12-16.
 */
public class MusicService extends Service implements MediaPlayer.OnCompletionListener {

    private MediaPlayer mediaPlayer;
    private boolean isStart = false;

    public static final int ACTION_START = 1;
    public static final int ACTION_PAUSE = 2;
    public static final int ACTION_RESTART = 3;
    public static final int ACTION_STOP = 4;
    public static final int ACTION_NEXT = 5;
    public static final int ACTION_CHECK = 6;

    public static final String STATE_KEY = "music_playing_action";

    public static final String POSITION_KEY = "music_position";

    public static final String AUTO_NEXT = "music_auto_next";

    private static final String TAG = "MusicService";

    private static MusicService self = null;

    public MusicService(){
        super();
        self = this;
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        int action = intent.getIntExtra("action", -1);
        switch (action) {
            case ACTION_START:
                String source = intent.getStringExtra("source");
                start(source);
                break;
            case ACTION_PAUSE:
                pause();
                break;
            case ACTION_RESTART:
                restart();
                break;
            case ACTION_STOP:
                stop();
                break;
            case ACTION_NEXT:
                start(null);
                break;
            case ACTION_CHECK:
                break;
                default:
        }
        callRefreshView();
        return START_NOT_STICKY;
    }

    private void stop() {
        if (mediaPlayer != null && mediaPlayer.isPlaying()) {
            mediaPlayer.stop();
            mediaPlayer.release();
            mediaPlayer = null;
        }
        SharedPreferences sharedPreferences = getSharedPreferences();
        sharedPreferences.edit().putInt(STATE_KEY, ACTION_STOP).apply();
    }

    private SharedPreferences getSharedPreferences() {
        return getApplicationContext().getSharedPreferences(getString(R.string.key_configuration), MODE_PRIVATE);
    }

    public void start(String source){
        if (source == null || source.equals("")) {
            SharedPreferences sharedPreferences = getSharedPreferences();
            int state = sharedPreferences.getInt(STATE_KEY,-1);
            if (state == ACTION_PAUSE && mediaPlayer != null) {
                mediaPlayer.start();
                sharedPreferences.edit().putInt(STATE_KEY, ACTION_START).apply();
                return;
            }
            List<Map<String, String>> cache = readCache();
            if (cache != null && cache.size() > 0) {
                int position = getCurrentPosition();
                if (position >= cache.size() || position < 0) {
                    position = 0;
                }
                source = cache.get(position).get("path");
                setCurrentPosition(position);
            }else {
                return;
            }
        }

        File file = new File(source);
        if (!file.exists()) {
            Toast.makeText(getApplicationContext(), "文件不存在", Toast.LENGTH_SHORT).show();
            //todo 重建xml
            return;
        }

        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.release();
            mediaPlayer = null;
        }
        try {
            mediaPlayer = createMediaPlayer();
            mediaPlayer.setDataSource(getApplicationContext(), Uri.fromFile(file));
            mediaPlayer.prepare();
            mediaPlayer.start();
            SharedPreferences sharedPreferences = getSharedPreferences();
            sharedPreferences.edit().putInt(STATE_KEY, ACTION_START).apply();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private MediaPlayer createMediaPlayer() {
        MediaPlayer mediaPlayer = new MediaPlayer();
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        mediaPlayer.setOnCompletionListener(this);
        AudioAttributes audioAttributes =new AudioAttributes.Builder()
                .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
                .build();
        mediaPlayer.setAudioAttributes(audioAttributes);
        return mediaPlayer;
    }

    public void pause(){
        if (mediaPlayer == null) {
            return;
        }
        if (mediaPlayer.isPlaying()) {
            mediaPlayer.pause();
            isStart = false;
        }

        SharedPreferences sharedPreferences = getSharedPreferences();
        sharedPreferences.edit().putInt(STATE_KEY, ACTION_PAUSE).apply();
    }

    public void restart(){
        if (mediaPlayer == null) {
            return;
        }
        mediaPlayer.start();
        isStart = true;
        SharedPreferences sharedPreferences = getSharedPreferences();
        sharedPreferences.edit().putInt(STATE_KEY, ACTION_RESTART).apply();
    }

    private static final String cacheFileName = "songs";

    public List<Map<String,String>> readCache(){
        Log.d(TAG, "readCache: load xml");
        File folder = getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
        File file = new File(folder.getAbsolutePath() + "/" +cacheFileName+ ".xml");
        if (file.exists()){
            try {
                DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder();
                Document document = builder.parse(file);
                NodeList songs = document.getElementsByTagName("song");
                List<Map<String, String>> list = new LinkedList<>();
                for (int i = 0; i < songs.getLength(); i++) {
                    Node node = songs.item(i);
                    NodeList song = node.getChildNodes();
                    Map<String, String> songMap = new HashMap<>();
                    for (int j = 0; j < song.getLength(); j++) {
                        Node son = song.item(j);
                        if (son.getNodeName().equals("path")) {
                            songMap.put("path", son.getTextContent());
                        } else if (son.getNodeName().equals("name")) {
                            songMap.put("name", son.getTextContent());
                        } else if (son.getNodeName().equals("index")) {
                            songMap.put("index", son.getTextContent());
                        }
                    }
                    list.add(songMap);
                }
                return list;
            } catch (ParserConfigurationException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (SAXException e) {
                e.printStackTrace();
            }
            return  new LinkedList<>();
        }else{
            return  new LinkedList<>();
        }
    }

    public int getCurrentPosition(){
        SharedPreferences sharedPreferences = getSharedPreferences();
        return sharedPreferences.getInt(MusicService.POSITION_KEY, -1);
    }

    public void setCurrentPosition(int currentPosition){
        SharedPreferences sharedPreferences = getSharedPreferences();
        sharedPreferences.edit().putInt(MusicService.POSITION_KEY, currentPosition).commit();
    }

    public static void interupt(){
        if (self == null) {
            return;
        }
        self.pause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        stop();
        Log.d(TAG, "onDestroy: stop music");
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        if (getSharedPreferences().getBoolean(AUTO_NEXT, true)) {
            int currentPosition = getCurrentPosition();
            currentPosition++;
            setCurrentPosition(currentPosition);
            start(null);
            callRefreshView();
        }
    }

    private void callRefreshView() {
        Log.d(TAG, "callRefreshView: call");
        Intent intent = new Intent();
        intent.setAction("priv.blackbibo.application.activity.MusicActivity.RefreshViewReceiver");
        sendBroadcast(intent);
    }
}
